
using System;
using System.Collections.Generic;
using Libs.LEvent;
using YooAsset;

namespace Client.Base
{
    /// <summary>
    /// 补丁进程
    /// </summary>
    public class PatchProcess
    {
        public long totalDownloadBytes = 0;
        public int totalDownloadCount = 0;
        private long currentDownloadBytes = 0;
        private int currentDownloadCount = 0;
        private StateMachine<Type> stateMachine;
        private Dictionary<string, string> packageVersions = new();
        private LEvents<int> events = new();
        private List<ResourceDownloaderOperation> downloaders = new();
        public readonly EPlayMode playMode;
        public readonly bool IsSimulation = true;


        public string Url { get; private set; }

        public PatchProcess(EPlayMode playMode)
        {
#if !UNITY_EDITOR
            //IsSimulation = false;
#endif
            this.playMode = playMode;
            stateMachine = new StateMachine<Type>(typeof(FsmRequsetPatchInfo));
            InitErrorEvent();
            InitStates();
        }

        public void Execute()
        {
            this.Log("PatchProcedure is Running");
            stateMachine.Execute();
        }

        private void InitStates()
        {

            AddState(new FsmRequsetPatchInfo(this));
            AddState(new FsmInitPackage(this));
            AddState(new FsmRequestPackageVersion(this));
            AddState(new FsmUpdatePackageManifest(this));
            AddState(new FsmCreateDownloader(this));
            AddState(new FsmDownloadPackageFiles(this));
            AddState(new FsmDownloadPackageOver(this));
            AddState(new FsmStartGame(this));
        }

        private void InitErrorEvent()
        {
            events.AddListener(Event_PatchError.EVENT_PATCHERROR, (e) =>
            {
                Event_PatchError error = e as Event_PatchError;
                this.Log(error.message);
                if (error.status == 1401)  //请求补丁信息失败
                {

                }
                else if (error.status == 1402)  //更新本地资源版本失败
                {

                }
                else if (error.status == 1403) //更新资源清单失败
                {

                }

            });
        }

        public void DownloadErrorCallback(DownloadErrorData data)
        {

        }

        public void DownloadUpdateCallback(DownloadUpdateData data)
        {
            currentDownloadBytes += data.CurrentDownloadBytes;
            currentDownloadCount += data.CurrentDownloadCount;
        }
        public bool TryTransition<T>()
        {
            return stateMachine.TryTransition(typeof(T));
        }
        public void SetPackageVersion(string packageName, string packageVersion)
        {
            packageVersions.TryAdd(packageName, packageVersion);
        }

        public string GetPackageVersion(string packageName)
        {
            if (packageVersions.TryGetValue(packageName, out var version))
            {
                return version;
            }
            return "1.0";
        }
        public void SetDownloaders(List<ResourceDownloaderOperation> downloaders)
        {
            this.downloaders = downloaders;
            foreach (var downloader in downloaders)
            {
                totalDownloadBytes += downloader.TotalDownloadBytes;
                totalDownloadCount += downloader.TotalDownloadCount;
            }
        }
        public List<ResourceDownloaderOperation> GetDownloaders()
        {
            return downloaders;
        }
        private void AddState(PatchState state)
        {
            stateMachine.AddState(state.GetType(), state.OnEnter, state.OnExit);
        }

        public void Call(int key, Event_PatchError event_PatchError)
        {
            events.CallNow(key, event_PatchError);
        }
    }

}
